package com.ziiwee.reduce.describe.creators.handlers;

import com.ziiwee.reduce.commons.utils.StringUtil;
import com.ziiwee.reduce.describe.FieldDescribe;
import com.ziiwee.reduce.describe.HandlerDescribe;
import com.ziiwee.reduce.describe.ResourceMethod;
import com.ziiwee.reduce.describe.creators.HandlerDescribeCreator;
import com.ziiwee.reduce.describe.models.FieldDescribeModel;
import com.ziiwee.reduce.describe.models.HandlerDescribeModel;
import org.springframework.core.ResolvableType;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

public abstract class AbstractRestHandlerCreator implements HandlerDescribeCreator, HandlerDescribe {

    public abstract ResourceMethod getResourceMethod();

    public abstract Class<?> getEntityClass();

    public abstract String getBasePattern();

    @Override
    public String getId() {
        return UUID.randomUUID().toString();
    }

    @Override
    public List<String> getMethods() {
        return Collections.singletonList(getResourceMethod().getHttpMethod());
    }

    @Override
    public List<String> getPatterns() {
        String name = StringUtil.firstToLowerCase(getEntityClass().getSimpleName());
        name = StringUtil.hasLength(getBasePattern()) ? getBasePattern() : name;
        if (Objects.equals(name.substring(0, 1), "/")) {
            name = name.substring(1);
        }
        if (Objects.equals(name.substring(name.length() - 1), "/")) {
            name = name.substring(0, name.length() - 1);
        }
        return Collections.singletonList(String.format(getResourceMethod().getPattern(), name));
    }

    @Override
    public String getName() {
        return getResourceMethod().getMethodName();
    }

    @Override
    public String getLabel() {
        return getResourceMethod().getLabel();
    }

    @Override
    public String getDescription() {
        return "";
    }

    @Override
    public HandlerDescribe create() {
        return new HandlerDescribeModel(getName(), getType(), getLabel(), getDescription(), getMethods(), getPatterns(), getParameters(), getId());
    }

    protected FieldDescribe getIdProperty(ResolvableType idType) {
        return new FieldDescribeModel("id", idType, "ID", "", false, true, true, null, null);
    }

    @Override
    public ResolvableType getType() {
        return ResolvableType.forClass(getEntityClass());
    }
}
